home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / shellforms / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-05-09  |  54.3 KB

  1. Subject:  v14i093:  Forms interface for shell scripts, Part02/02
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Paul Lew <harvard!gsg!lew@a.cs.uiuc.edu>
  7. Posting-number: Volume 14, Issue 93
  8. Archive-name: shellforms/part02
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive, meaning:
  14. # 1. Remove everything above the #! /bin/sh line.
  15. # 2. Save the resulting text in a file.
  16. # 3. Execute the file with /bin/sh (not csh) to create the files:
  17. #    sf.c form.c load.c field.c selection.c keyword.c option.c
  18. #    msg.c term.c io.c summary.c
  19. export PATH; PATH=/bin:$PATH
  20. echo shar: extracting "'sf.c'" '(4115 characters)'
  21. if test -f 'sf.c'
  22. then
  23.     echo shar: will not over-write existing file "'sf.c'"
  24. else
  25. sed 's/^X//' << \SHAR_EOF > 'sf.c'
  26. X/**************************************************************************
  27. X*
  28. X* File name:    sf.c
  29. X*
  30. X* Author:    Paul Lew, General Systems Group, Inc. Salem NH
  31. X* Created at:    05/08/86  10:11 AM
  32. X* Last update:    02/08/88  00:23 AM  (Edition: 29)
  33. X*
  34. X* Description:    This program will take standard input  (if no argument
  35. X*        specified in  command line) or  the specified  file as
  36. X*        form  template and  display   it  on  the terminal  to
  37. X*        perform basic form editing function.  It then generate
  38. X*        the Csh  or Bourne shell set script  on  stdout  to be
  39. X*        executed (ala tset -s).
  40. X*
  41. X*        This program is designed to  give programmer  an  easy
  42. X*        way of doing form filling in shell level.
  43. X*
  44. X* Update History:
  45. X*
  46. X*    Date    Modification Description                By
  47. X*  --------    ------------------------------------------------------    ---
  48. X*  05/08/86    Initial version                        Lew
  49. X*  08/04/87    added Help_display flag                    Lew
  50. X*  12/29/87    modify to add Bourne shell output flag, use getopt()    Lew
  51. X*  01/12/88    added init_sno(), added CTRL L redisplay function,    Lew
  52. X*        added signal trap handling.
  53. X*  01/26/88    added AUTOTAB at end of a field, added NUMERIC field    Lew
  54. X*        attribute
  55. X*  02/08/88    modified to add perl script output flag            Lew
  56. X*
  57. X***************************************************************************/
  58. X#define    EXTERN
  59. X#include    <stdio.h>
  60. X#include    <ctype.h>
  61. X#include    "form.h"
  62. X#include    "basic.h"
  63. X
  64. Xchar    *Version = "1.8  02/08/88  00:21 AM";
  65. Xchar    *Bugs = "Bug report send to: decvax!gsg!lew (UUCP)";
  66. Xchar    *Copyright = "Copyright by Paul Lew (1987,1988) All rights reserved";
  67. Xchar    *Prgname;            /* program name */
  68. X
  69. Xextern    unsigned char    Shell;
  70. Xextern    int        Help_display;
  71. Xint            Debug = NO;
  72. X
  73. X/*------------------------------------------------------------07/13/84--+
  74. X|                                    |
  75. X|        M a i n    R o u t i n e    S t a r t s    H e r e        |
  76. X|                                    |
  77. X+----------------------------------------------------------------------*/
  78. Xmain (argc, argv)
  79. Xint    argc;        /* number of argument passed */
  80. Xchar    **argv;        /* pointer to argument list */
  81. X    {
  82. X    int        n;        /* number of files (so far 2)    */
  83. X    char        *fname;        /* form file name */
  84. X
  85. X    Prgname = *argv;
  86. X    n = procarg (argc, argv);
  87. X    if (n == argc) fname = NULL;    /* read from stdin if no input    */
  88. X    else fname = argv[n];
  89. X    edit_form (fname, (int (*)())NULL);
  90. X    exit (0);
  91. X    }
  92. X
  93. X/*----------------------------------------------------------------------+
  94. X|                                    |
  95. X|    proc_arg : process input argument and set global flags        |
  96. X|                                    |
  97. X+----------------------------------------------------------------------*/
  98. Xprocarg (argc, argv)
  99. Xint    argc;
  100. Xchar    **argv;
  101. X    {
  102. X    int        rvideo = 0;
  103. X    int        undline = 0;
  104. X    int        hilite = 0;
  105. X    char        *fname = NULL;
  106. X    int        c;
  107. X    extern    char    *optarg;    /* ptr to argument */
  108. X    extern    int    optind;        /* remember which one to process next */
  109. X
  110. X    ENTER (procarg);
  111. X    while ((c = getopt (argc, argv, "Hbdhmo:pru")) != EOF) {
  112. X        switch (c) {
  113. X            when 'b': Shell = BOURNE;
  114. X            when 'd': Debug = YES;
  115. X            when 'h': hilite = YES;
  116. X            when 'm': Help_display = YES;
  117. X            when 'o': fname = optarg;
  118. X            when 'p': Shell = PERL;
  119. X            when 'r': rvideo = YES;
  120. X            when 'u': undline = YES;
  121. X            otherwise:help ();
  122. X                  exit (1);
  123. X            }
  124. X        }
  125. X    set_options (hilite, rvideo, undline, fname);
  126. X    RETURN (optind);
  127. X    }
  128. X
  129. X/*-------------------------------------------------------------05/08/86-+
  130. X|                                    |
  131. X|               help : display help message            |
  132. X|                                    |
  133. X+----------------------------------------------------------------------*/
  134. Xhelp ()
  135. X    {
  136. X    ENTER(help);
  137. X    fprintf (stderr, "%s Version %s\r\n", Prgname, Version);
  138. X    fprintf (stderr, "Command Options:\r\n");
  139. X    fprintf (stderr, "  -H        display this help message\r\n");
  140. X    fprintf (stderr, "  -b        generate Bourne shell output [Csh]\r\n");
  141. X    fprintf (stderr, "  -d        debug mode, will show CTRL chars\r\n");
  142. X    fprintf (stderr, "  -h        input in highlight mode\r\n");
  143. X    fprintf (stderr, "  -m        display selection help automatically\r\n");
  144. X    fprintf (stderr, "  -o file   use file as output file\r\n");
  145. X    fprintf (stderr, "  -p        generate perl script output\r\n");
  146. X    fprintf (stderr, "  -r        input in reverse video mode\r\n");
  147. X    fprintf (stderr, "  -u        input in underline mode\r\n");
  148. X    EXIT;
  149. X    }
  150. SHAR_EOF
  151. if test 4115 -ne "`wc -c < 'sf.c'`"
  152. then
  153.     echo shar: error transmitting "'sf.c'" '(should have been 4115 characters)'
  154. fi
  155. fi # end of overwriting check
  156. echo shar: extracting "'form.c'" '(5898 characters)'
  157. if test -f 'form.c'
  158. then
  159.     echo shar: will not over-write existing file "'form.c'"
  160. else
  161. sed 's/^X//' << \SHAR_EOF > 'form.c'
  162. X/* Last update: 02/08/88  00:18 AM  (Edition: 56) */
  163. X#include    <stdio.h>
  164. X#include    <ctype.h>
  165. X#include    <signal.h>
  166. X#include    "form.h"
  167. X#include    "field.h"
  168. X#include    "term.h"
  169. X#include    "basic.h"
  170. X
  171. Xchar    Screen [SCRLINE][SCRCOL+1];
  172. Xchar    Form_name[20] = "";        /* current form name */
  173. Xchar    Exitc;                /* field exit char */
  174. Xchar    Enter_mode [20];        /* display before input field */
  175. Xchar    Exit_mode [20];            /* display after input field */
  176. X
  177. Xstruct    field    Field[MAXFIELD];    /* field nodes */
  178. Xint        Fno;            /* next field to use (or count) */
  179. Xunsigned char    Fhead[SCRLINE];        /* 1st field index on each line */
  180. Xunsigned char    Flcount[SCRLINE];    /* number of fields on this line */
  181. Xunsigned char    Lastdata = 24;        /* last line with data on form */
  182. X
  183. Xchar    Varfile [MAXFNAME];        /* output variable file name */
  184. X
  185. Xextern    int        Form_msg;    /* defined in msg.c */
  186. Xextern    unsigned char    Shell;        /* output shell script type */
  187. X
  188. Xint    sig_interrupt();
  189. Xint    sig_stop();
  190. X
  191. X/*----------------------------------------------------------------------+
  192. X|                                    |
  193. X|        show_form : display a given form file            |
  194. X|                                    |
  195. X+----------------------------------------------------------------------*/
  196. Xshow_form (fname)
  197. Xchar    *fname;        /* name of form file, NULL = stdin, 1 = redisplay */
  198. X    {
  199. X    int        i, j;
  200. X    int        idx;        /* index to current field */
  201. X    unsigned    size;
  202. X    unsigned    off;
  203. X    unsigned    len;        /* string length */
  204. X    int        pend;        /* previous end position */
  205. X    char        *lp;        /* line pointer (for speed) */
  206. X    char        *p;
  207. X    extern    char    *Prgname;
  208. X
  209. X    ENTER(show_form);
  210. X    if (fname != (char *)1 &&        /* redisplay */
  211. X        (fname == NULL || strcmp (fname, Form_name) != 0)) {
  212. X        if (!load_form (fname)) RETURN (0);
  213. X        }
  214. X
  215. X    screen (SCR_ERASE);
  216. X    for (i=0; i<SCRLINE; i++) {
  217. X        p = lp = Screen[i];
  218. X        if (Flcount[i] != 0) {
  219. X            pend = 0;
  220. X            for (j=0, idx=Fhead[i]; j<Flcount[i]; j++, idx++) {
  221. X                size = Field[idx].f_len;
  222. X                off = Field[idx].f_off;
  223. X                put_string (p, off-pend);
  224. X                put_string (Enter_mode, 0); 
  225. X                put_string (lp + off, size);
  226. X                put_string (Exit_mode, 0);
  227. X                p = lp + off + size;
  228. X                pend = off + size;
  229. X                }
  230. X            }
  231. X        if ((len = strlen (p)) == 0) continue;
  232. X        put_string (p, len);
  233. X        put_char ('\r');
  234. X        }
  235. X    RETURN (1);
  236. X    }
  237. X
  238. X/*----------------------------------------------------------------------+
  239. X|                                    |
  240. X|       edit_form : edit a form on all the input fields        |
  241. X|                                    |
  242. X+----------------------------------------------------------------------*/
  243. Xedit_form (fname, action)
  244. Xchar    *fname;        /* name of the form to edit */
  245. Xint    (*action) ();    /* action routine to check at end of each field */
  246. X    {
  247. X    unsigned    fdx = 0;    /* current cursor in field index */
  248. X    struct    field    *fp;        /* pointer to current edit field */
  249. X    int        n;        /* action routine return status */
  250. X    int        efopt;        /* option to edit field */
  251. X
  252. X    ENTER(edit_form);
  253. X    signal (SIGINT, sig_interrupt);
  254. X    signal (SIGTSTP, sig_stop);
  255. X
  256. X    term_init ();
  257. X    cbreakio (1);
  258. X    if (!show_form (fname)) goto end;
  259. X    if (Fno == 0) goto end;
  260. X    form_msg ((char *)NULL, 1, 1);
  261. X    screen (SCR_KEYXMIT);
  262. X    while (1) {
  263. X        fp = &Field[fdx];
  264. X        efopt = EF_BOF;
  265. X        do    {
  266. X            if (fp->f_attr & FA_SELECTION) sel_field (fdx);
  267. X            else edit_field (fdx, efopt);
  268. X            if (!action) break;
  269. X            n = (*action) (fdx, &Screen[fp->f_line-1][fp->f_off],
  270. X                    fp->f_len, Exitc);
  271. X            switch (n) {
  272. X                when EF_ERR:    efopt = EF_BOF;
  273. X                when EF_FILL:    efopt = EF_FILL;
  274. X                }
  275. X            } while (n != EF_OK);
  276. X        if ((Exitc & 0x80) == 0x80) {
  277. X            switch (Exitc & 0x7f) {
  278. X                when KU:    Exitc = CTRL('P');
  279. X                when KD:    Exitc = CTRL('N');
  280. X                }
  281. X            }
  282. X        switch (Exitc) {
  283. X            when CTRL('L'):    show_form ((char *)1);
  284. X            when CTRL('M'): goto wrout;
  285. X            when CTRL('J'):    goto wrout;
  286. X            when CTRL('P'):    fdx = closest (fdx, -1);
  287. X            when CTRL('N'):    fdx = closest (fdx, 1);
  288. X            when CTRL('T'): fdx = (fdx == 0) ? Fno-1 : (fdx-1);
  289. X            when CTRL('I'): if (++fdx == Fno) fdx = 0;
  290. X            otherwise:    show_summary ();
  291. X                    show_form ((char *)1);
  292. X            }
  293. X        }
  294. Xwrout:    write_var ();
  295. X    poscur (Lastdata, (unsigned char)1, "\n"); screen (SCR_EEOL);
  296. Xend:
  297. X    screen (SCR_NOKEYXMIT);
  298. X    cbreakio (0);
  299. X    term_close ();
  300. X    EXIT;
  301. X    }
  302. X
  303. X/*-------------------------------------------------------------05/08/86-+
  304. X|                                    |
  305. X|           write_var : write field variables to a file        |
  306. X|                                    |
  307. X+----------------------------------------------------------------------*/
  308. Xwrite_var ()
  309. X    {
  310. X    register int    i;
  311. X    FILE        *fd;        /* output file pointer */
  312. X    char        *p;
  313. X    char        *op;
  314. X    char        c;
  315. X    char        buf[80+1];
  316. X    char        obuf[80+1];
  317. X    struct    field    *f;
  318. X
  319. X    ENTER(write_var);
  320. X    if (!strlen (Varfile)) EXIT;
  321. X
  322. X    if ((fd = fopen (Varfile, "w")) == NULL) {
  323. X        fprintf (stderr, "write_var: can not open file %s for write\r\n",
  324. X             Varfile);
  325. X        exit (1);
  326. X        }
  327. X
  328. X    for (i=0; i<Fno; i++) {
  329. X        f = &Field[i];
  330. X        if (f-> f_var != NULL) {
  331. X            get_field (i, buf);
  332. X            p = buf;  op = obuf;
  333. X            while (c = *p++) {
  334. X                switch (c) {
  335. X                    when '\'':    if (Shell== PERL) *op++ = '\\';
  336. X                        else    {
  337. X                            *op++ ='\'';*op++ ='"';
  338. X                            *op++ ='\'';*op++ ='"';
  339. X                            }
  340. X                    when '!':    if (Shell == CSH) *op++ = '\\';
  341. X                    }
  342. X                *op++ = c;
  343. X                }
  344. X            *op = EOS;
  345. X            fprintf (fd, "%s%s='%s'%s\n",
  346. X                 (Shell==CSH)?"set ":((Shell==PERL)?"$":""),
  347. X                 f-> f_var, obuf,
  348. X                 (Shell == PERL) ? ";" : "");
  349. X            }
  350. X        }
  351. X    fclose (fd);
  352. X    EXIT;
  353. X    }
  354. X
  355. X/*-------------------------------------------------------------01/12/88-+
  356. X|                                    |
  357. X|         sig_interrupt : Interrupt signal handler        |
  358. X|                                    |
  359. X+----------------------------------------------------------------------*/
  360. Xsig_interrupt ()
  361. X    {
  362. X    ENTER (sig_interrupt);
  363. X    form_msg ("Aborted by user\n", 24+1, 1);
  364. X    screen (SCR_NORMAL);
  365. X    cbreakio (1);
  366. X    exit (1);
  367. X    }
  368. X
  369. X/*-------------------------------------------------------------01/12/88-+
  370. X|                                    |
  371. X|              sig_stop : Stop signal handler            |
  372. X|                                    |
  373. X+----------------------------------------------------------------------*/
  374. Xsig_stop ()
  375. X    {
  376. X    ENTER (sig_stop);
  377. X    form_msg ("stopped by user\n", 24+1, 1);
  378. X    screen (SCR_NORMAL);
  379. X    cbreakio (0);
  380. X    kill (getpid(), SIGSTOP);
  381. X    put_string ("Press CTRL L to refresh display: ", 33);
  382. X    cbreakio (1);
  383. X    }
  384. SHAR_EOF
  385. if test 5898 -ne "`wc -c < 'form.c'`"
  386. then
  387.     echo shar: error transmitting "'form.c'" '(should have been 5898 characters)'
  388. fi
  389. fi # end of overwriting check
  390. echo shar: extracting "'load.c'" '(8779 characters)'
  391. if test -f 'load.c'
  392. then
  393.     echo shar: will not over-write existing file "'load.c'"
  394. else
  395. sed 's/^X//' << \SHAR_EOF > 'load.c'
  396. X/* Last update: 01/26/88  10:53 PM  (Edition: 63) */
  397. X#include    <stdio.h>
  398. X#include    <strings.h>
  399. X#include    "form.h"
  400. X#include    "field.h"
  401. X#include    "basic.h"
  402. X
  403. X#define    TOKENSIZE    256
  404. X
  405. Xchar    Varname [MAXVNAME];        /* variable name string pool */
  406. Xchar    *Varwp = Varname;        /* next write position */
  407. X
  408. Xextern    char        Screen[SCRLINE][SCRCOL+1];
  409. Xextern    char        Form_name[];
  410. Xextern    unsigned char    Fhead[];    /* 1st field index on each line */
  411. Xextern    unsigned char    Flcount[];    /* number of fields on this line */
  412. Xextern    unsigned char    Lastdata;
  413. Xextern    struct    field    Field[];    /* field nodes */
  414. Xextern    int        Fno;        /* next field to use (or count) */
  415. X
  416. X/*----------------------------------------------------------------------+
  417. X|                                    |
  418. X|        load_form : load a form from disk file            |
  419. X|                                    |
  420. X+----------------------------------------------------------------------*/
  421. Xload_form (fname)
  422. Xchar    *fname;
  423. X    {
  424. X    FILE            *fp;
  425. X    register unsigned char    i;
  426. X
  427. X    ENTER (load_form);
  428. X    if (fname == NULL) fp = stdin;
  429. X    else if ((fp = fopen (fname, "r")) == 0) {
  430. X        fprintf (stderr, "Can not open form file %s\r\n", fname);
  431. X        RETURN (0);
  432. X        }
  433. X    for (i=0; i<SCRLINE; i++) Screen[i][0] = '\0';
  434. X    init_field ();
  435. X    for (i=0; i<SCRLINE; i++) {
  436. X        if (fgets (Screen[i], SCRCOL+1, fp) == 0) break;
  437. X        if (Screen[i][0] == CTRL('L')) {
  438. X            Screen[i][0] = EOS;
  439. X            field_attr (fp);
  440. X            break;
  441. X            }
  442. X        make_field (i+1, Screen[i]);
  443. X        }
  444. X    init_sno ();        /* fill data for field with selections */
  445. X    Lastdata = i;
  446. X    if (fname != NULL) {
  447. X        strcpy (Form_name, fname);
  448. X        }
  449. X    RETURN (1);
  450. X    }
  451. X
  452. X/*----------------------------------------------------------------------+
  453. X|                                    |
  454. X|    bcopy : copy len byte from src to dest (extra fill with blanks)    |
  455. X|                                    |
  456. X+----------------------------------------------------------------------*/
  457. Xbcopy (dest, src, len)
  458. Xchar        *dest;
  459. Xchar        *src;
  460. Xunsigned    len;
  461. X    {
  462. X    char        c = ' ';
  463. X
  464. X    ENTER (bcopy);
  465. X    while (len-- != 0) {
  466. X        if (c == EOS) *dest++ = ' ';    /* fill blanks to end */
  467. X        else if ((c = *src++) != EOS)
  468. X            *dest++ = c;
  469. X        else    *dest++ = ' ';
  470. X        }
  471. X    EXIT;
  472. X    }
  473. X
  474. X/*-------------------------------------------------------------05/08/86-+
  475. X|                                    |
  476. X|       add_var : add a variable name to field structure        |
  477. X|                                    |
  478. X+----------------------------------------------------------------------*/
  479. Xadd_var (fno, name)
  480. Xint    fno;
  481. Xchar    *name;
  482. X    {
  483. X    int        len = strlen (name) + 1;
  484. X
  485. X    ENTER (add_var);
  486. X    if (Varwp + len >= &Varname[MAXVNAME]) {
  487. X        fprintf (stderr, "add_var: no more space for variable name\r\n");
  488. X        exit (1);
  489. X        }
  490. X    Field[fno].f_var = Varwp;
  491. X    strcpy (Varwp, name);
  492. X    Varwp += len;
  493. X    EXIT;
  494. X    }
  495. X
  496. X/*-------------------------------------------------------------05/08/86-+
  497. X|                                    |
  498. X|      field_attr : read in field attribute of the form        |
  499. X|                                    |
  500. X+----------------------------------------------------------------------*/
  501. Xfield_attr (fd)
  502. XFILE    *fd;
  503. X    {
  504. X    int        field = -1;
  505. X    char        tokbuf [TOKENSIZE];    /* token value */
  506. X    char        token;            /* token specifier */
  507. X    int        i, n;
  508. X    unsigned    len, size;
  509. X    struct    field    *f;
  510. X    char        *p;
  511. X
  512. X    ENTER (field_attr);
  513. X    while (token = get_token (fd, tokbuf)) {
  514. X        switch (token) {
  515. X            when 'v': if (++field >= Fno) RETURN (0);
  516. X                  add_var (field, tokbuf);
  517. X            when 's': n = (field < 0) ? 0 : field;
  518. X                  f = &Field[n];
  519. X                  size = strlen(tokbuf);
  520. X                  build_selection (f, tokbuf, size);
  521. X            when 'h': n = (field < 0) ? 0 : field;
  522. X                  f = &Field[n];
  523. X                  build_help_msg (f, tokbuf);
  524. X            when 'd': n = (field < 0) ? 0 : field;
  525. X                  f = &Field[n];
  526. X                  size = strlen(tokbuf);
  527. X                  len = (size > f-> f_len) ? f-> f_len : size;
  528. X                  for (p=tokbuf, i=0; i<len; i++) {
  529. X                      Screen[f-> f_line - 1][f-> f_off + i] = *p++;
  530. X                      }
  531. X            when 'a': n = (field < 0) ? 0 : field;
  532. X                  f = &Field[n];
  533. X                  set_field_attr (f, tokbuf);
  534. X            otherwise:fprintf (stderr, "unknown token %c (field %d)\r\n",
  535. X                       token, field);    
  536. X            }
  537. X        }
  538. X    RETURN (1);
  539. X    }
  540. X
  541. X/*-------------------------------------------------------------05/08/86-+
  542. X|                                    |
  543. X|     get_token : return next token in field description section    |
  544. X|                                    |
  545. X+----------------------------------------------------------------------*/
  546. Xget_token (fd, tokbuf)
  547. XFILE    *fd;
  548. Xchar    *tokbuf;
  549. X    {
  550. X    static    char    buf[TOKENSIZE];
  551. X    static    char    *p;
  552. X    static    int    len = 0;
  553. X    static    char    dchar;
  554. X    register char    *tp;        /* temp pointer */
  555. X    char        token;
  556. X
  557. X    ENTER (get_token);
  558. X    if (len == 0) {
  559. X        do    {
  560. X            if (!fgets (buf, sizeof (buf), fd)) RETURN ((char)0);
  561. X            len = strlen (buf) - 1;        /* no NL */
  562. X            } while (len == 0);
  563. X        dchar = buf[0];        /* delimiter char */
  564. X        p = buf + 1;        /* 1st char */
  565. X        }
  566. X
  567. X    for (tp=p; tp < &buf[len]; ) {
  568. X        if (*tp++ == dchar) break;
  569. X        }
  570. X
  571. X    token = *p++;            /* return token char */
  572. X    p++;                /* skip =, actually ignore it */
  573. X    while (p < tp-1)
  574. X        *tokbuf++ = *p++;
  575. X    *tokbuf = EOS;
  576. X
  577. X    if ((p = tp) == &buf[len]) len = 0;
  578. X    RETURN (token);
  579. X    }
  580. X  
  581. X/*----------------------------------------------------------------------+
  582. X|                                    |
  583. X|    make_field : extract input fields to make field structure    |
  584. X|                                    |
  585. X+----------------------------------------------------------------------*/
  586. Xmake_field (lno, line)
  587. Xunsigned    lno;        /* line number of this line */
  588. Xchar        *line;
  589. X    {
  590. X    char        *p;
  591. X    unsigned    col = 1;    /* current column position */
  592. X    unsigned    in_field = 0;    /* number of input field char */
  593. X    unsigned    cno;
  594. X
  595. X    ENTER (make_field);
  596. X    for (p=line; *p != EOS; p++) {
  597. X        switch (*p) {
  598. X            case '~':     /* input field */
  599. X                *p = ' ';
  600. X                if (in_field++ == 0) cno = col;
  601. X                col++;
  602. X                break;
  603. X            case '\t':
  604. X                col = ((col-1)/8 + 1) * 8 + 1;
  605. X                goto lab;
  606. X            default:
  607. X                col++;
  608. Xlab:                if (in_field)
  609. X                    add_field (lno, cno, p-line-in_field,
  610. X                           in_field);
  611. X                in_field = 0;
  612. X            }
  613. X        }
  614. X    EXIT;
  615. X    }
  616. X
  617. X/*----------------------------------------------------------------------+
  618. X|                                    |
  619. X|    init_field : initialize all field control related data        |
  620. X|                                    |
  621. X+----------------------------------------------------------------------*/
  622. Xinit_field ()
  623. X    {
  624. X    int        i;
  625. X
  626. X    ENTER (init_field);
  627. X    Fno = 0;
  628. X    for (i=0; i<SCRLINE; i++) {
  629. X        Fhead[i] = 0;
  630. X        Flcount[i] = 0;
  631. X        }
  632. X    EXIT;
  633. X    }
  634. X/*----------------------------------------------------------------------+
  635. X|                                    |
  636. X|        add_field : add a given field to field structure        |
  637. X|                                    |
  638. X+----------------------------------------------------------------------*/
  639. Xadd_field (line, column, offset, len)
  640. Xunsigned    line;        /* line of the field */
  641. Xunsigned    column;        /* column of the field */
  642. Xunsigned    offset;        /* char offset from beginning of the line */
  643. Xunsigned    len;        /* field size */
  644. X    {
  645. X    struct    field    *fp;
  646. X
  647. X    ENTER (add_field);
  648. X    if (Fno >= MAXFIELD) {
  649. X        fprintf (stderr, "Too many fields in a screen max=%d\r\n",
  650. X             MAXFIELD);
  651. X        exit (1);
  652. X        }
  653. X    fp = &Field[Fno];
  654. X    fp-> f_line = line;
  655. X    fp-> f_col = column;
  656. X    fp-> f_off = offset;
  657. X    fp-> f_len = len;
  658. X    fp-> f_attr = 0;        /* 'a' -- attribute */
  659. X    fp-> f_sel = NULL;        /* 's' -- selection */
  660. X    fp-> f_help = NULL;        /* 'h' -- help message */
  661. X    fp-> f_sno = 0;
  662. X    fp-> f_var = NULL;
  663. X    if (Flcount[line-1]++ == 0) {
  664. X        Fhead[line-1] = Fno;
  665. X        }
  666. X    Fno++;
  667. X    EXIT;
  668. X    }
  669. X
  670. X#define    STRNEQ(x,y,n)    ((*(x) == *(y)) && strncmp (x,y,n) == 0)
  671. X#define    BADINIT    "Field %d, Init value: [%.*s] no in selection list, ignored\n"
  672. X/*-------------------------------------------------------------01/11/88-+
  673. X|                                    |
  674. X|       init_sno : initialize selection number for preloaded fields    |
  675. X|                                    |
  676. X+----------------------------------------------------------------------*/
  677. Xinit_sno ()
  678. X    {
  679. X    register int    idx, j;
  680. X    int        field_count;
  681. X    int        init_size;    /* initial default data size */
  682. X    struct    field    *f;
  683. X    char        *p;
  684. X
  685. X    ENTER (init_sno);
  686. X    for (idx=0; idx<Fno; idx++) {
  687. X
  688. X        f = &Field[idx];
  689. X        p = &Screen[f-> f_line - 1][f-> f_off];
  690. X        init_size = fldlen (p, f-> f_len);
  691. X
  692. X        if (f-> f_sel != NULL) {
  693. X        if (init_size) {
  694. X            field_count = sel_num (f);
  695. X            /* check if default data is in the selection list */
  696. X            for (j=0; j<field_count; j++) {
  697. X                register char    *selp;
  698. X                selp = f-> f_sel[j];
  699. X                if (STRNEQ (p, selp, strlen(selp))) {
  700. X                    f-> f_sno = j;
  701. X                    break;
  702. X                    }
  703. X                }
  704. X            if (j >= field_count) {
  705. X                fprintf (stderr, BADINIT, idx, init_size, p);
  706. X                j = 0;  goto mv_1st;
  707. X                }
  708. X            }
  709. X        else    {
  710. X            /* move the first selection into the field */
  711. X            j = 0;
  712. Xmv_1st:            strncpy (p, f-> f_sel[j], strlen(f-> f_sel[j]));
  713. X            }
  714. X        }
  715. X        }
  716. X    EXIT;
  717. X    }
  718. X
  719. X/*-------------------------------------------------------------01/26/88-+
  720. X|                                    |
  721. X|        set_field_attr : set attributes for a given field        |
  722. X|                                    |
  723. X+----------------------------------------------------------------------*/
  724. Xset_field_attr (fieldp, buf)
  725. Xstruct    field    *fieldp;
  726. Xchar        *buf;
  727. X    {
  728. X    char    c;
  729. X
  730. X    ENTER (set_field_attr);
  731. X    while ((c = *buf++) != EOS) {
  732. X        switch (c) {
  733. X            when 'd':    fieldp-> f_attr |= FA_NUMERIC;
  734. X            when 'a':    fieldp-> f_attr |= FA_AUTOTAB;
  735. X            when 'b':    fieldp-> f_attr |= FA_BLOCK;
  736. X            otherwise:    fprintf (stderr,
  737. X                     "unknown field attribute: %c\r\n", c);
  738. X                exit (1);
  739. X            }
  740. X        }
  741. X    EXIT;
  742. X    }
  743. SHAR_EOF
  744. if test 8779 -ne "`wc -c < 'load.c'`"
  745. then
  746.     echo shar: error transmitting "'load.c'" '(should have been 8779 characters)'
  747. fi
  748. fi # end of overwriting check
  749. echo shar: extracting "'field.c'" '(6631 characters)'
  750. if test -f 'field.c'
  751. then
  752.     echo shar: will not over-write existing file "'field.c'"
  753. else
  754. sed 's/^X//' << \SHAR_EOF > 'field.c'
  755. X/* Last update: 01/26/88  11:26 PM  (Edition: 25) */
  756. X#include    <stdio.h>
  757. X#include    <signal.h>
  758. X#include    <strings.h>
  759. X#include    <ctype.h>
  760. X#include    "term.h"
  761. X#include    "form.h"
  762. X#include    "field.h"
  763. X#include    "basic.h"
  764. X
  765. Xextern    int        Fno;
  766. Xextern    struct    field    Field[];
  767. Xextern    char        Screen[SCRLINE][SCRCOL+1];
  768. Xextern    char        Enter_mode[];
  769. Xextern    char        Exit_mode[];
  770. Xextern    int        Form_msg;
  771. Xextern    char        Exitc;
  772. X
  773. X/*-------------------------------------------------------------05/09/86-+
  774. X|                                    |
  775. X|          get_field : get a copy of field data to buffer        |
  776. X|                                    |
  777. X+----------------------------------------------------------------------*/
  778. Xget_field (fno, buf)
  779. Xint    fno;                /* field number */
  780. Xchar    *buf;                /* buffer to be filled */
  781. X    {
  782. X    struct    field    *f;
  783. X    char        *p;
  784. X    int        size;
  785. X
  786. X    ENTER(get_field);
  787. X    if (fno < 0 || fno >= Fno) EXIT;
  788. X    f = &Field[fno];
  789. X    p = &Screen [f-> f_line -1][f-> f_off];
  790. X    size = fldlen (p, f-> f_len);
  791. X    strncpy (buf, p, size);
  792. X    buf[size] = EOS;        /* mark the end */
  793. X    EXIT;
  794. X    }
  795. X/*----------------------------------------------------------------------+
  796. X|                                    |
  797. X|  fldlen : return the number of data in a field (skip trailing blanks) |
  798. X|                                    |
  799. X+----------------------------------------------------------------------*/
  800. Xfldlen (buf, size)
  801. Xchar        *buf;        /* pointer to field buffer */
  802. Xunsigned    size;        /* size of the field */
  803. X    {
  804. X    int        blank;
  805. X
  806. X    ENTER(fldlen);
  807. X    for (blank=0; buf[size-1-blank] == ' '; blank++) {
  808. X        if (blank >= size) break;
  809. X        }
  810. X    RETURN (size - blank);        /* return length of field */
  811. X    }
  812. X
  813. X/*----------------------------------------------------------------------+
  814. X|                                    |
  815. X|      upd_field : move data into a field and display it        |
  816. X|                                    |
  817. X+----------------------------------------------------------------------*/
  818. Xupd_field (idx, type, data)
  819. Xunsigned    idx;        /* field number (0 to Fno-1) */
  820. Xint        type;        /* type of output */
  821. Xint        data;        /* data, type may vary */
  822. X    {
  823. X    struct    field    *fp;
  824. X    char        *fmt;
  825. X    char        *scp;        /* pointer to screen buffer */
  826. X    char        buf[81];
  827. X    int        data2;        /* cents */
  828. X
  829. X    ENTER(upd_field);
  830. X    if (idx >= Fno) {
  831. X        fprintf (stderr,
  832. X             "Field number: %d out of range, max %d\r\n",
  833. X             idx, Fno);
  834. X        EXIT;
  835. X        }
  836. X    fp = &Field[idx];
  837. X    switch (type) {
  838. X        case UF_MONEY:    fmt = "%5d.%02d";
  839. X                data2 = data % 100;
  840. X                data = data / 100;    break;
  841. X        case UF_NUMBER: fmt = "%d";        break;
  842. X        case UF_STRING:
  843. X        default:    fmt = "%s";        break;
  844. X        }
  845. X    sprintf (buf, fmt, data, data2);
  846. X    scp = &Screen[fp-> f_line - 1][fp-> f_off];
  847. X    bcopy (scp, buf, (unsigned)fp-> f_len);
  848. X    poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  849. X    put_string (scp, fp-> f_len);
  850. X    poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  851. X    EXIT;
  852. X    }
  853. X
  854. X/*-------------------------------------------------------------07/14/87-+
  855. X|                                    |
  856. X|    closest : find the closest field above/below current line    |
  857. X|                                    |
  858. X+----------------------------------------------------------------------*/
  859. Xclosest (fno, direction)
  860. Xunsigned    fno;        /* current field number */
  861. Xint        direction;    /* compare direction: 1=below, -1=above */
  862. X    {
  863. X    struct    field    *fp = &Field[fno];
  864. X    int        col;        /* target column */
  865. X    int        line;        /* current line */
  866. X    int        diff;        /* current difference */
  867. X    int        mindiff = 100;    /* minimal difference */
  868. X    int        mini = 0;    /* minimal field index */
  869. X    register int    i;
  870. X
  871. X    ENTER(closest);
  872. X    col = fp->f_col;
  873. X    line = fp->f_line;
  874. X
  875. X    for (i=fno+direction; i != fno; i += direction) {
  876. X        if (i < 0) i = Fno-1;
  877. X        else if (i >= Fno) i = 0;
  878. X        fp = &Field[i];
  879. X        if (fp->f_line != line) break;
  880. X        }
  881. X    mini = i;
  882. X    for (line = fp->f_line; ; i += direction) {
  883. X        if (i < 0) i = Fno-1;
  884. X        else if (i >= Fno) i = 0;
  885. X        fp = &Field[i];
  886. X        if (fp->f_line != line) break;
  887. X        if ((diff = abs ((int)fp->f_col - (int)col)) == 0) RETURN (i);
  888. X        if (diff < mindiff) {
  889. X            mindiff = diff;
  890. X            mini = i;
  891. X            }
  892. X        }
  893. X    RETURN (mini);
  894. X    }
  895. X
  896. X/*----------------------------------------------------------------------+
  897. X|                                    |
  898. X|        edit_field : edit a given field in a form        |
  899. X|                                    |
  900. X+----------------------------------------------------------------------*/
  901. Xedit_field (idx, efopt)
  902. Xunsigned    idx;            /* index to Field array */
  903. Xint        efopt;            /* option */
  904. X    {
  905. X    struct    field    *fp;
  906. X    char        c;
  907. X    char        *p;
  908. X    char        *s;        /* beginning of field buffer */
  909. X    unsigned    n;
  910. X    register int    i;
  911. X
  912. X    ENTER (edit_field);
  913. X    fp = &Field[idx];
  914. X    poscur (fp-> f_line, fp-> f_col, Enter_mode);
  915. X    p = s = &Screen [fp-> f_line - 1][fp-> f_off];
  916. X    switch (efopt) {
  917. X        case EF_FILL:
  918. X        case EF_EOF:    n = fldlen (s, fp-> f_len);
  919. X                if (n != 0) {
  920. X                    if (efopt == EF_FILL)
  921. X                        put_string (p, n);
  922. X                    p += n;
  923. X                    }
  924. X                break;
  925. X        default:    ;    /* start at beginning of field */
  926. X        }
  927. X    while (1) {
  928. X        c = getkey ();
  929. X        if (Form_msg) {
  930. X            form_msg ((char *)NULL, fp-> f_line, fp-> f_col + (p-s));
  931. X            put_string (Enter_mode, 0);
  932. X            }
  933. X        if ((c & 0x80) == 0x80) {
  934. X            switch (c & 0x7f) {
  935. X                case KL:    goto cur_left;
  936. X                case KR:    goto cur_right;
  937. X                }
  938. X            }
  939. X        switch (c) {
  940. X            case '\177':        /* delete char */
  941. X                if (p > s) { *(--p) = ' '; screen (SCR_DEL); }
  942. X                continue;
  943. X            case CTRL('W'):        /* delete prev word */
  944. X                while (p > s) {
  945. X                    if (*(p-1) != ' ') break;
  946. X                    p--; screen (SCR_DEL);
  947. X                    }
  948. X                while (p > s) {
  949. X                    if (*(p-1) == ' ') break;
  950. X                    *(--p) = ' ';
  951. X                    screen (SCR_DEL);
  952. X                    }
  953. X                continue;
  954. X            case CTRL('K'):
  955. X                n = fldlen (s, fp-> f_len);
  956. X                for (i=0; i<n; i++) put_char (*(p+i) = ' ');
  957. X                for (i=0; i<n; i++) screen (SCR_BACKSPACE);
  958. X                continue;
  959. X            case CTRL('H'):
  960. X            case CTRL('B'):
  961. Xcur_left:            if (p > s) { p--; screen (SCR_BACKSPACE); }
  962. X                continue;
  963. X            case CTRL('F'):
  964. Xcur_right:            if (p < s + fp-> f_len) {
  965. X                    put_char (*p++);
  966. X                    }
  967. X                continue;
  968. X            case CTRL('G'):
  969. X            case CTRL('U'):
  970. X                while (p > s) {
  971. X                    *(--p) = ' ';  screen (SCR_DEL);
  972. X                    }
  973. X                continue;
  974. X            case CTRL('E'):        /* goto end of field */
  975. X                n = fldlen (s, fp-> f_len);
  976. X                p = s + n;
  977. X                poscur (fp-> f_line, fp-> f_col + n, (char *)NULL);
  978. X                continue;
  979. X            case CTRL('A'):        /* emacs style */
  980. X                p = s;
  981. X                poscur (fp-> f_line, fp-> f_col, (char *)NULL);
  982. X                continue;
  983. X            case CTRL('O'):
  984. X                prev_msg ();
  985. X                continue;
  986. X            default:
  987. X                if ((fp-> f_attr & FA_NUMERIC) != 0 &&
  988. X                     isprint (c) && !isdigit (c)) {
  989. X                    put_char (CTRL('G'));
  990. X                    form_msg ("Numeric field, 0-9 only",
  991. X                          fp-> f_line,
  992. X                          fp-> f_col + (p-s));
  993. X                    continue;
  994. X                    }
  995. X                if (c < LOW_GCHAR || c > HIGH_GCHAR) {
  996. X                    Exitc = c;    /* save exit char */
  997. X                    goto eoe;
  998. X                    }
  999. X            }
  1000. X        if (p - s >= fp-> f_len) { put_char (CTRL('G')); continue; }
  1001. X        *p++ = c;
  1002. X        put_char (c);
  1003. X        if ((fp-> f_attr & FA_AUTOTAB) != 0 && p - s == fp-> f_len) {
  1004. X            Exitc = TAB;        /* tab to next field */
  1005. X            break;
  1006. X            }
  1007. X        }
  1008. X    /* *p = EOS will put a marker at the end of buffer */
  1009. Xeoe:    put_string (Exit_mode, 0);
  1010. X    RETURN (p-s);
  1011. X    }
  1012. SHAR_EOF
  1013. if test 6631 -ne "`wc -c < 'field.c'`"
  1014. then
  1015.     echo shar: error transmitting "'field.c'" '(should have been 6631 characters)'
  1016. fi
  1017. fi # end of overwriting check
  1018. echo shar: extracting "'selection.c'" '(5773 characters)'
  1019. if test -f 'selection.c'
  1020. then
  1021.     echo shar: will not over-write existing file "'selection.c'"
  1022. else
  1023. sed 's/^X//' << \SHAR_EOF > 'selection.c'
  1024. X/* Last update: 01/27/88  00:04 AM  (Edition: 45) */
  1025. X#include    <stdio.h>
  1026. X#include    <sys/ioctl.h>
  1027. X#include    <ctype.h>
  1028. X#include    <strings.h>
  1029. X#include    "term.h"
  1030. X#include    "form.h"
  1031. X#include    "field.h"
  1032. X#include    "basic.h"
  1033. X
  1034. Xint    Help_display = NO;        /* if YES, display help */
  1035. X
  1036. Xextern    struct    field    Field[];
  1037. Xextern    char        Enter_mode[];
  1038. Xextern    char        Exit_mode[];
  1039. Xextern    int        Form_msg;
  1040. Xextern    char        Exitc;
  1041. Xextern    char        *malloc();
  1042. Xextern    char        *calloc();
  1043. X/*
  1044. X    Selection buffer looks like:
  1045. X
  1046. X    <delchr> string1 <delchr> string2 <delchr> ... stringn <delchr>
  1047. X
  1048. X    The first character in the buffer will be used as the delimiter to
  1049. X    separate selection strings.  The last delimiter character is optional,
  1050. X    i.e., EOS will also terminate the last selection string.
  1051. X*/
  1052. X
  1053. X/*-------------------------------------------------------------08/01/87-+
  1054. X|                                    |
  1055. X|     build_selection : take selection definition and create a list    |
  1056. X|                                    |
  1057. X+----------------------------------------------------------------------*/
  1058. Xbuild_selection (fldp, buf, len)
  1059. Xstruct    field    *fldp;            /* ptr to field structure */
  1060. Xchar        *buf;            /* selection strings */
  1061. Xunsigned    len;            /* length of string */
  1062. X    {
  1063. X    register char    *p = (char *)malloc(len+1);
  1064. X    register char    **tp;
  1065. X    register int    i;
  1066. X    char        delimiter = buf[0];    /* selection delimiter */
  1067. X    char        c;
  1068. X    unsigned    cnt = 0;        /* # of selections */
  1069. X    char        *tmp[50];        /* temp array */
  1070. X
  1071. X    ENTER(build_selection);
  1072. X    if (len == 0) len = strlen (buf);
  1073. X    while (len-- != 0) {
  1074. X        if ((c = *buf++) == delimiter) {
  1075. X            *p++ = EOS;
  1076. X            if (cnt >= 50) {
  1077. X                /* silent ignored extra for now */
  1078. X                }
  1079. X            else tmp[cnt++] = p;
  1080. X            }
  1081. X        else    *p++ = c;
  1082. X        }
  1083. X    fldp->f_sel = tp = (char **) malloc (sizeof (char *) * (cnt + 1));
  1084. X    for (i=0; i<cnt; i++) *tp++ = tmp[i];
  1085. X    *tp = NULL;
  1086. X    fldp->f_attr |= FA_SELECTION;
  1087. X    RETURN (0);
  1088. X    }
  1089. X
  1090. X/*-------------------------------------------------------------08/01/87-+
  1091. X|                                    |
  1092. X|    sel_num : return the number of selections in a given field    |
  1093. X|                                    |
  1094. X+----------------------------------------------------------------------*/
  1095. Xsel_num (fldp)
  1096. Xstruct    field    *fldp;
  1097. X    {
  1098. X    register int    i = 0;
  1099. X    register char    **pp = fldp-> f_sel;
  1100. X
  1101. X    ENTER(sel_num);
  1102. X    while (*pp++ != NULL) i++;
  1103. X    RETURN (i);
  1104. X    }
  1105. X
  1106. X/*-------------------------------------------------------------08/01/87-+
  1107. X|                                    |
  1108. X|    sel_field : allow user to select a selection from the list    |
  1109. X|                                    |
  1110. X+----------------------------------------------------------------------*/
  1111. Xsel_field (idx)
  1112. Xunsigned    idx;            /* index to Field array */
  1113. X    {
  1114. X    struct    field    *fldp = &Field[idx];
  1115. X    int        n = fldp-> f_sno;    /* selection number */
  1116. X    int        selno;            /* # of possible selections */
  1117. X    int        i = -1;
  1118. X    char        c;
  1119. X
  1120. X    ENTER(sel_field);
  1121. X    selno = sel_num (fldp);
  1122. X    poscur (fldp-> f_line, fldp-> f_col, Enter_mode);
  1123. X    upd_field (idx, UF_STRING, fldp-> f_sel[n]);
  1124. X    while (1) {
  1125. X        int    might_tab;
  1126. X        if (Help_display) display_help (fldp, n);
  1127. X        c = getkey ();
  1128. X        might_tab = 0;
  1129. X        if (Form_msg) {
  1130. X            form_msg ((char *)NULL, fldp->f_line, fldp->f_col);
  1131. X            put_string (Enter_mode, 0);
  1132. X            }
  1133. X        if ((c & 0x80) == 0x80) {
  1134. X            switch (c & 0x7f) {
  1135. X                case KL:    goto prev_sel;
  1136. X                case KR:    goto next_sel;
  1137. X                }
  1138. X            }
  1139. X        switch (c) {
  1140. X            case ' ':
  1141. X            case CTRL('F'):
  1142. Xnext_sel:            if (++n >= selno) n = 0;  break;
  1143. X            case CTRL('H'):
  1144. Xprev_sel:            if (--n < 0) n = selno-1; break;
  1145. X            case '?':
  1146. X                if (!Help_display) {
  1147. X                    display_help (fldp, n);
  1148. X                    break;
  1149. X                    }
  1150. X            default:if (c < LOW_GCHAR || c > HIGH_GCHAR) {
  1151. X                    Exitc = c;
  1152. X                    goto eoe;
  1153. X                    }
  1154. X                i = cmp1st (c, fldp->f_sel, i+1);
  1155. X                if (i < 0) continue;
  1156. X                might_tab = 1;
  1157. X                n = i;
  1158. X            }
  1159. X        upd_field (idx, UF_STRING, fldp-> f_sel[n]);
  1160. X        if (might_tab && (fldp->f_attr & FA_AUTOTAB) != 0) {
  1161. X            Exitc = TAB;
  1162. X            break;
  1163. X            }
  1164. X        }
  1165. Xeoe:    put_string (Exit_mode, 0);
  1166. X    fldp-> f_sno = n;        /* save selection number */
  1167. X    EXIT;
  1168. X    }    
  1169. X
  1170. X/*-------------------------------------------------------------08/03/87-+
  1171. X|                                    |
  1172. X|       cmp1st : compare 1st character in a keyword list        |
  1173. X|                                    |
  1174. X+----------------------------------------------------------------------*/
  1175. Xcmp1st (c, list, start)
  1176. Xchar    c;                /* char to compare */
  1177. Xchar    **list;                /* keyword list */
  1178. Xint    start;                /* start entry index */
  1179. X    {
  1180. X    register int    i, j;
  1181. X    register int    n;
  1182. X
  1183. X    ENTER(cmp1st);
  1184. X    if (list == NULL || list[0] == NULL) RETURN (-1);
  1185. X    for (n=0; list[n] != NULL; n++);
  1186. X    for (i=start, j=0; j<n; i++, j++) {
  1187. X        if (i >= n) i = 0;
  1188. X        if ((c | 0x20) == (list[i][0] | 0x20)) RETURN (i);
  1189. X        }
  1190. X    RETURN (-1);            /* no match */
  1191. X    }
  1192. X
  1193. X/*-------------------------------------------------------------08/04/87-+
  1194. X|                                    |
  1195. X|        build_help_msg : build help message list        |
  1196. X|                                    |
  1197. X+----------------------------------------------------------------------*/
  1198. Xbuild_help_msg (fldp, buf)
  1199. Xstruct    field    *fldp;            /* field where the msg belongs */
  1200. Xchar        *buf;            /* message stores here */
  1201. X    {
  1202. X    unsigned    len = strlen (buf);
  1203. X    unsigned    n;
  1204. X    register int    i;
  1205. X    register char    *p;
  1206. X
  1207. X    ENTER(build_help_msg);
  1208. X    n = sel_num (fldp);
  1209. X    if (fldp-> f_help == NULL) {        /* first time call */
  1210. X        fldp-> f_help = (char **) calloc(n+1, sizeof(char *));
  1211. X        }
  1212. X    for (i=0; i<n; i++) {
  1213. X        if (fldp-> f_help[i] == NULL) break;
  1214. X        }
  1215. X    if (i < n) {
  1216. X        fldp-> f_help[i] = p = (char *) malloc (len + 1);
  1217. X        strcpy (p, buf);
  1218. X        }
  1219. X    EXIT;
  1220. X    }
  1221. X
  1222. X/*-------------------------------------------------------------08/04/87-+
  1223. X|                                    |
  1224. X|       display_help : display help message on message line        |
  1225. X|                                    |
  1226. X+----------------------------------------------------------------------*/
  1227. Xdisplay_help (fldp, i)
  1228. Xstruct    field    *fldp;            /* field pointer */
  1229. Xint        i;            /* index to help message */
  1230. X    {
  1231. X    char        *p;
  1232. X    int        numchar;    /* # of pending input chars */
  1233. X
  1234. X    ENTER(display_help);
  1235. X    if (fldp-> f_help == NULL) EXIT;
  1236. X    p = fldp-> f_help[i];
  1237. X    if (p != NULL) {
  1238. X        ioctl (0, FIONREAD, &numchar);
  1239. X        if (numchar == 0) form_msg (p, fldp->f_line, fldp->f_col);
  1240. X        }
  1241. X    EXIT;
  1242. X    }
  1243. SHAR_EOF
  1244. if test 5773 -ne "`wc -c < 'selection.c'`"
  1245. then
  1246.     echo shar: error transmitting "'selection.c'" '(should have been 5773 characters)'
  1247. fi
  1248. fi # end of overwriting check
  1249. echo shar: extracting "'keyword.c'" '(1253 characters)'
  1250. if test -f 'keyword.c'
  1251. then
  1252.     echo shar: will not over-write existing file "'keyword.c'"
  1253. else
  1254. sed 's/^X//' << \SHAR_EOF > 'keyword.c'
  1255. X/* Last update: 01/13/88  10:43 AM  (Edition: 5) */
  1256. X#include    <stdio.h>
  1257. X#include    "basic.h"
  1258. X/*----------------------------------------------------------------------+
  1259. X|                                    |
  1260. X|    fill_keyword : fill the field with possible matched keyword    |
  1261. X|                                    |
  1262. X+----------------------------------------------------------------------*/
  1263. Xfill_keyword (buf, len, list)
  1264. Xchar        *buf;
  1265. Xunsigned    len;            /* size of input field */
  1266. Xchar        **list;
  1267. X    {
  1268. X    int        i, j;
  1269. X    unsigned    flen;        /* field length */
  1270. X    unsigned char    match[80];
  1271. X    ENTER (fill_keyword);
  1272. X    flen = fldlen (buf, len);
  1273. X    for (i=j=0; list[i] != NULL; i++) {
  1274. X        if (kwcmp (buf, list[i], flen) == 0) {
  1275. X            /* find a match */
  1276. X            match[j++] = i;
  1277. X            }
  1278. X        }
  1279. X    if (j == 1) bcopy (buf, list[match[0]], len);
  1280. X    else if (j > 1)     bcopy (buf, list[match[0]], flen);
  1281. X    RETURN (j);
  1282. X    }
  1283. X/*----------------------------------------------------------------------+
  1284. X|                                    |
  1285. X|    kwcmp : compare a word with keyword (case insensitive)        |
  1286. X|                                    |
  1287. X+----------------------------------------------------------------------*/
  1288. Xkwcmp (src, dest, len)
  1289. Xchar        *src;
  1290. Xchar        *dest;
  1291. Xunsigned    len;
  1292. X    {
  1293. X    ENTER (kwcmp);
  1294. X    while (len-- != 0) {
  1295. X        if ((*src++ | 0x20) != (*dest++ | 0x20))
  1296. X             RETURN (1);            /* no match */
  1297. X        }
  1298. X    RETURN (0);        /* match found */
  1299. X    }
  1300. SHAR_EOF
  1301. if test 1253 -ne "`wc -c < 'keyword.c'`"
  1302. then
  1303.     echo shar: error transmitting "'keyword.c'" '(should have been 1253 characters)'
  1304. fi
  1305. fi # end of overwriting check
  1306. echo shar: extracting "'option.c'" '(1317 characters)'
  1307. if test -f 'option.c'
  1308. then
  1309.     echo shar: will not over-write existing file "'option.c'"
  1310. else
  1311. sed 's/^X//' << \SHAR_EOF > 'option.c'
  1312. X/* Last update: 01/13/88  11:17 AM  (Edition: 5) */
  1313. X#include    <stdio.h>
  1314. X#include    <strings.h>
  1315. X#include    "form.h"
  1316. X#include    "basic.h"
  1317. X
  1318. Xunsigned char    Rvideo;            /* reverse video */
  1319. Xunsigned char    Undline;        /* under line */
  1320. Xunsigned char    Hilite;            /* high light */
  1321. Xunsigned char    Shell = CSH;        /* output script type */
  1322. X
  1323. Xextern    char    Varfile[];
  1324. Xextern    char    Enter_mode[];
  1325. Xextern    char    Exit_mode[];
  1326. X/*-------------------------------------------------------------05/08/86-+
  1327. X|                                    |
  1328. X|           set_options : set form editor options            |
  1329. X|                                    |
  1330. X+----------------------------------------------------------------------*/
  1331. Xset_options (hilite, rvideo, undline, fname)
  1332. Xint    hilite;                /* highlight attribute */
  1333. Xint    rvideo;                /* reverse video attribute */
  1334. Xint    undline;            /* underline attribute */
  1335. Xchar    *fname;                /* output variable file name */
  1336. X    {
  1337. X    char        sbuf [80];    /* set mode */
  1338. X    char        ebuf [80];    /* exit mode */
  1339. X
  1340. X    ENTER(set_options);
  1341. X
  1342. X    sbuf[0] = ebuf[0] = EOS;
  1343. X    if (hilite) {
  1344. X        get_hilite (sbuf, ebuf);
  1345. X        strcat (Enter_mode, sbuf);
  1346. X        strcat (Exit_mode, ebuf);
  1347. X        }
  1348. X    if (undline) {
  1349. X        get_undline (sbuf, ebuf);
  1350. X        strcat (Enter_mode, sbuf);
  1351. X        strcat (Exit_mode, ebuf);
  1352. X        }
  1353. X    if (rvideo) {
  1354. X        get_rvideo (sbuf, ebuf);
  1355. X        strcat (Enter_mode, sbuf);
  1356. X        strcat (Exit_mode, ebuf);
  1357. X        }
  1358. X    if (fname) strncpy (Varfile, fname, MAXFNAME);
  1359. X    EXIT;
  1360. X    }
  1361. SHAR_EOF
  1362. if test 1317 -ne "`wc -c < 'option.c'`"
  1363. then
  1364.     echo shar: error transmitting "'option.c'" '(should have been 1317 characters)'
  1365. fi
  1366. fi # end of overwriting check
  1367. echo shar: extracting "'msg.c'" '(2999 characters)'
  1368. if test -f 'msg.c'
  1369. then
  1370.     echo shar: will not over-write existing file "'msg.c'"
  1371. else
  1372. sed 's/^X//' << \SHAR_EOF > 'msg.c'
  1373. X/* Last update: 01/13/88  10:59 AM  (Edition: 11) */
  1374. X#include    <stdio.h>
  1375. X#include    <strings.h>
  1376. X#include    "basic.h"
  1377. X#include    "form.h"
  1378. X/*
  1379. X    Two flavors to display message:
  1380. X
  1381. X    form_msg    display message then  position cursor at given
  1382. X            position, this allows form filling on terminal
  1383. X            without cursor save restore capability.
  1384. X
  1385. X    formmsg        display  message and return   to  the caller's
  1386. X            position  using terminal's save/restore cursor
  1387. X            ability. This is designed to be used  by field
  1388. X            checking routine where  user don't know  where
  1389. X            the field is.
  1390. X*/
  1391. X
  1392. X#define MAXSMSG 5
  1393. X#define MSGSIZE 132
  1394. X
  1395. Xint    Form_msg = 0;            /* form message on screen flag */
  1396. X
  1397. Xstatic    char    Savemsg [MAXSMSG][MSGSIZE];
  1398. Xstatic    int    Sdx = 0;        /* number of next entry to use */
  1399. Xstatic    int    Smcount = 0;        /* number of messages saved */
  1400. X/*----------------------------------------------------------------------+
  1401. X|                                    |
  1402. X|        form_msg : display message on the message line        |
  1403. X|                                    |
  1404. X+----------------------------------------------------------------------*/
  1405. Xform_msg (s, line, col)
  1406. Xchar        *s;        /* message to display, if NULL, clear message */
  1407. Xunsigned char    line;        /* line to go at end */
  1408. Xunsigned char    col;        /* column to go at end */
  1409. X    {
  1410. X    ENTER (form_msg);
  1411. X    poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
  1412. X    screen (SCR_REVERSE);
  1413. X    screen (SCR_EEOL);
  1414. X    if (s) {
  1415. X        Form_msg = 1;
  1416. X        put_string (s, 0);
  1417. X        save_msg (s);
  1418. X        }
  1419. X    else    Form_msg = 0;
  1420. X    poscur (line, col, (char *)NULL);
  1421. X    EXIT;
  1422. X    }
  1423. X/*----------------------------------------------------------------------+
  1424. X|                                    |
  1425. X|      formmsg : form_msg () use terminal SC, RC feature        |
  1426. X|                                    |
  1427. X+----------------------------------------------------------------------*/
  1428. Xformmsg (s)
  1429. Xchar    *s;        /* message to display, if NULL, clear message */
  1430. X    {
  1431. X    ENTER (formmsg);
  1432. X    screen (SCR_SAVE);
  1433. X    poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
  1434. X    screen (SCR_REVERSE);
  1435. X    screen (SCR_EEOL);
  1436. X    if (s) {
  1437. X        Form_msg = 1;
  1438. X        put_string (s, 0);
  1439. X        save_msg (s);
  1440. X        }
  1441. X    else    Form_msg = 0;
  1442. X    screen (SCR_RESTORE);
  1443. X    EXIT;
  1444. X    }
  1445. X  
  1446. X/*----------------------------------------------------------------------+
  1447. X|                                    |
  1448. X|        save_msg : save a message on the message buffer        |
  1449. X|                                    |
  1450. X+----------------------------------------------------------------------*/
  1451. Xsave_msg (s)
  1452. Xchar    *s;
  1453. X    {
  1454. X    ENTER (save_msg);
  1455. X    strncpy (Savemsg[Sdx], s, MSGSIZE);
  1456. X    if (++Sdx >= MAXSMSG) Sdx = 0;
  1457. X    if (Smcount < MAXSMSG) Smcount++;
  1458. X    EXIT;
  1459. X    }
  1460. X/*----------------------------------------------------------------------+
  1461. X|                                    |
  1462. X|        prev_msg : display previously displayed message        |
  1463. X|                                    |
  1464. X+----------------------------------------------------------------------*/
  1465. Xprev_msg ()
  1466. X    {
  1467. X    ENTER (prev_msg);
  1468. X    if (!Smcount) return (0);
  1469. X    /* This routine actually pop the message stored */
  1470. X    if (--Sdx < 0) Sdx = MAXSMSG-1;
  1471. X    screen (SCR_SAVE);
  1472. X    poscur ((unsigned char)24, (unsigned char)1, (char *)NULL);
  1473. X    screen (SCR_REVERSE);
  1474. X    screen (SCR_EEOL);
  1475. X    put_string (Savemsg[Sdx], 0);
  1476. X    Form_msg = 1;
  1477. X    screen (SCR_RESTORE);
  1478. X    RETURN (1);
  1479. X    }
  1480. SHAR_EOF
  1481. if test 2999 -ne "`wc -c < 'msg.c'`"
  1482. then
  1483.     echo shar: error transmitting "'msg.c'" '(should have been 2999 characters)'
  1484. fi
  1485. fi # end of overwriting check
  1486. echo shar: extracting "'term.c'" '(6575 characters)'
  1487. if test -f 'term.c'
  1488. then
  1489.     echo shar: will not over-write existing file "'term.c'"
  1490. else
  1491. sed 's/^X//' << \SHAR_EOF > 'term.c'
  1492. X/* Last update: 01/13/88  11:16 AM  (Edition: 9) */
  1493. X#include    <stdio.h>
  1494. X#include    <ctype.h>
  1495. X#include    <strings.h>
  1496. X#include    "form.h"
  1497. X
  1498. X#define    YES    (1)
  1499. X#define    NO    (0)
  1500. X#define    EOS    '\0'
  1501. X#define    when        break; case
  1502. X#define    otherwise    break;default
  1503. X
  1504. Xstatic    char    *Erase = "\010 \010";    /* erase string */
  1505. X
  1506. Xstruct    tcap    {
  1507. X    char        *tc_id;        /* key for capability    */
  1508. X    char        *tc_str;    /* ptr to Tc_str area    */
  1509. X    unsigned char    tc_delay;    /* # of msec to delay    */
  1510. X    unsigned char    tc_len;        /* length of tc_str    */
  1511. X    };
  1512. X
  1513. Xstatic    char    Termcap [1024];
  1514. Xstatic    char    Tstr [1024];        /* buffer for real escape sequence */
  1515. Xstatic    char    *Tsp = Tstr;        /* pointer to be used by tgetstr */
  1516. Xstatic    int    Tcap_count = 0;        /* # of entries extracted */
  1517. X
  1518. X/*-------- You may want to modify the following (also term.h) ----------*/
  1519. X#include    "term.h"
  1520. X
  1521. Xstatic    struct    tcap Tcap [] = {
  1522. X        { "bc",    0, NULL, 0 },    /* cursor backspace        */
  1523. X        { "cm",    0, NULL, 0 },    /* cursor motion        */
  1524. X        { "cl", 0, NULL, 0 },    /* clear entire screen        */
  1525. X        { "cd", 0, NULL, 0 },    /* clear to end of display    */
  1526. X        { "ce", 0, NULL, 0 },    /* clear to end of line        */
  1527. X        { "ho", 0, NULL, 0 },    /* home cursor            */
  1528. X        { "ks", 0, NULL, 0 },    /* start keypad xmit mode    */
  1529. X        { "ke", 0, NULL, 0 },    /* end keypad xmit mode        */
  1530. X        { "ku", 0, NULL, 0 },    /* (input) cursor upper        */
  1531. X        { "kd", 0, NULL, 0 },    /* (input) cursor down        */
  1532. X        { "kl", 0, NULL, 0 },    /* (input) cursor left        */
  1533. X        { "kr", 0, NULL, 0 },    /* (input) cursor right        */
  1534. X        { "md", 0, NULL, 0 },    /* mode dim (or highlite)    */
  1535. X        { "me", 0, NULL, 0 },    /* mode end (return to normal)    */
  1536. X        { "rc", 0, NULL, 0 },    /* restore cursor        */
  1537. X        { "sc", 0, NULL, 0 },    /* save cursor            */
  1538. X        { "so", 0, NULL, 0 },    /* start reverse video mode    */
  1539. X        { "se", 0, NULL, 0 },    /* end                */
  1540. X        { "us", 0, NULL, 0 },    /* start underline mode     */
  1541. X        { "ue", 0, NULL, 0 },    /* end                */
  1542. X        { NULL, 0, NULL, 0 }
  1543. X    };
  1544. X
  1545. Xchar    *getenv ();
  1546. Xchar    *tgetstr ();
  1547. Xchar    *tgoto ();
  1548. X
  1549. X/*-------------------------------------------------------------05/10/86-+
  1550. X|                                    |
  1551. X|          tcap_init : initialize termcap data structure        |
  1552. X|                                    |
  1553. X+----------------------------------------------------------------------*/
  1554. Xtcap_init ()
  1555. X    {
  1556. X    struct    tcap    *p;
  1557. X    char        *tp;
  1558. X    unsigned int    delay;
  1559. X    int        status;
  1560. X    char        *termtype = getenv ("TERM");
  1561. X
  1562. X    if ((status = tgetent (Termcap, termtype)) != 1) {
  1563. X        if (status == 0) {
  1564. X            fprintf (stderr, "No entry for %s in termcap\r\n",
  1565. X                 termtype);
  1566. X            }
  1567. X        else    fprintf (stderr, "Can not open termcap file\r\n");
  1568. X        exit (1);
  1569. X        }
  1570. X
  1571. X    for (p= &Tcap[0]; p->tc_id != EOS; p++) {
  1572. X        tp = tgetstr (p-> tc_id, &Tsp);
  1573. X        if (tp == NULL) {     /* no such capability */
  1574. X            if (p == &Tcap[BC]) tp = "\010";
  1575. X            else tp = "";
  1576. X            }
  1577. X        delay = 0;
  1578. X        while (isdigit (*tp)) {
  1579. X            delay = delay*10 + (*tp++) - '0';
  1580. X            }
  1581. X        p->tc_str = tp;
  1582. X        p->tc_delay = delay;
  1583. X        p->tc_len = strlen (tp);
  1584. X        Tcap_count++;
  1585. X        }
  1586. X    }
  1587. X
  1588. X/*----------------------------------------------------------------------+
  1589. X|                                    |
  1590. X|        screen : common screen operation routine        |
  1591. X|                                    |
  1592. X+----------------------------------------------------------------------*/
  1593. Xscreen (code)
  1594. Xint    code;        /* operation code */
  1595. X    {
  1596. X    int        n = BAD;    /* init to not valid entry */
  1597. X    struct    tcap    *te;
  1598. X
  1599. X    if (Tcap_count == 0) tcap_init ();
  1600. X    switch (code) {
  1601. X        when SCR_DEL:        put_string (Erase, 0);
  1602. X        when SCR_BACKSPACE:    n = BC;
  1603. X        when SCR_ERASE:        n = CL;
  1604. X        when SCR_HOME:        n = HO;
  1605. X        when SCR_EEOL:        n = CE;
  1606. X        when SCR_SAVE:        n = SC;
  1607. X        when SCR_KEYXMIT:    n = KS;
  1608. X        when SCR_NOKEYXMIT:    n = KE;
  1609. X        when SCR_RESTORE:    n = RC;
  1610. X        when SCR_REVERSE:    n = SO;
  1611. X        when SCR_NORMAL:    n = SE;
  1612. X        otherwise:    ;    /* ignore it */
  1613. X        }
  1614. X    if (n != BAD) {
  1615. X        te = &Tcap[n];
  1616. X        delay (te-> tc_delay);
  1617. X        put_string (te-> tc_str, (unsigned)te-> tc_len);
  1618. X        }
  1619. X    }
  1620. X/*----------------------------------------------------------------------+
  1621. X|                                    |
  1622. X|       poscur : position cursor on line, column on screen        |
  1623. X|                                    |
  1624. X+----------------------------------------------------------------------*/
  1625. Xposcur (line, column, s)
  1626. Xunsigned char    line;
  1627. Xunsigned char    column;
  1628. Xchar        *s;        /* option string to output at line, column */
  1629. X    {
  1630. X    char    *p;
  1631. X
  1632. X    if (Tcap_count == 0) tcap_init ();
  1633. X    p = tgoto (Tcap[CM].tc_str, column-1, line-1);
  1634. X    delay (Tcap[CM].tc_delay);
  1635. X    put_string (p, 0);
  1636. X    if (s != NULL) put_string (s, 0);
  1637. X    }
  1638. X
  1639. X/*-------------------------------------------------------------05/10/86-+
  1640. X|                                    |
  1641. X|      delay : delay output for n msec (actually write NULL)        |
  1642. X|                                    |
  1643. X+----------------------------------------------------------------------*/
  1644. Xstatic
  1645. Xdelay (n)
  1646. Xunsigned char    n;            /* # of msec to delay */
  1647. X    {
  1648. X    static    char    c = EOS;
  1649. X    register int    i;
  1650. X
  1651. X    if (n == 0) return;
  1652. X
  1653. X    for (i=0; i<n; i++) {
  1654. X        write (fileno (stdout), &c, 1);
  1655. X        }
  1656. X    }
  1657. X
  1658. X/*-------------------------------------------------------------05/11/86-+
  1659. X|                                    |
  1660. X|          Routines to get mode-specific strings            |
  1661. X|                                    |
  1662. X+----------------------------------------------------------------------*/
  1663. Xget_undline (sbuf, ebuf)
  1664. Xchar    *sbuf;                /* enter mode buffer */
  1665. Xchar    *ebuf;                /* exit mode buffer */
  1666. X    {
  1667. X    if (Tcap_count == 0) tcap_init ();
  1668. X    strcpy (sbuf, Tcap[US].tc_str);
  1669. X    strcpy (ebuf, Tcap[UE].tc_str);
  1670. X    }
  1671. X
  1672. Xget_hilite (sbuf, ebuf)
  1673. Xchar    *sbuf;                /* enter mode buffer */
  1674. Xchar    *ebuf;                /* exit mode buffer */
  1675. X    {
  1676. X    if (Tcap_count == 0) tcap_init ();
  1677. X    strcpy (sbuf, Tcap[MD].tc_str);
  1678. X    strcpy (ebuf, Tcap[ME].tc_str);
  1679. X    }
  1680. X
  1681. Xget_rvideo (sbuf, ebuf)
  1682. Xchar    *sbuf;                /* enter mode buffer */
  1683. Xchar    *ebuf;                /* exit mode buffer */
  1684. X    {
  1685. X    if (Tcap_count == 0) tcap_init ();
  1686. X    strcpy (sbuf, Tcap[SO].tc_str);
  1687. X    strcpy (ebuf, Tcap[SE].tc_str);
  1688. X    }
  1689. X
  1690. X/*-------------------------------------------------------------07/05/87-+
  1691. X|                                    |
  1692. X|        getkey : get user entered key (handle cursor key)        |
  1693. X|                                    |
  1694. X+----------------------------------------------------------------------*/
  1695. Xgetkey ()
  1696. X    {
  1697. X    char        buf[20];    /* temporary hold the input stream */
  1698. X    char        c;
  1699. X    register int    i = 0;
  1700. X    register int    ci = 0;        /* current matched index */
  1701. X    int        idx;
  1702. X    char        match;        /* flag, YES/NO */
  1703. X    char        kmatch [4];    /* record how may char matched in
  1704. X                       each key (KU, KD, KL, KR) */
  1705. X    extern char    get_char();
  1706. X
  1707. X    for (i=0; i<4; i++) kmatch[i] = 0;
  1708. Xloop:
  1709. X    c = get_char () & 0x7f;            /* make it ASCII */
  1710. X    for (match=NO, i=0; i<4; i++) {
  1711. X        if (kmatch[i] < ci) continue;
  1712. X        switch (i) {
  1713. X            when 0: idx = KU;
  1714. X            when 1: idx = KD;
  1715. X            when 2: idx = KL;
  1716. X            when 3: idx = KR;
  1717. X            }
  1718. X        if (c == Tcap[idx].tc_str[ci]) {
  1719. X            kmatch[i]++;
  1720. X            if (Tcap[idx].tc_len == ci+1) {
  1721. X                ci = 0;
  1722. X                return (0x80 | idx);
  1723. X                }
  1724. X            match = YES;
  1725. X            }
  1726. X        }
  1727. X    buf[ci++] = c;        /* save input char in temp buffer */
  1728. X    if (match == YES) goto loop;
  1729. X
  1730. X    pushback (&buf[1], ci-1);
  1731. X    return (buf[0]);
  1732. X    }
  1733. SHAR_EOF
  1734. if test 6575 -ne "`wc -c < 'term.c'`"
  1735. then
  1736.     echo shar: error transmitting "'term.c'" '(should have been 6575 characters)'
  1737. fi
  1738. fi # end of overwriting check
  1739. echo shar: extracting "'io.c'" '(4106 characters)'
  1740. if test -f 'io.c'
  1741. then
  1742.     echo shar: will not over-write existing file "'io.c'"
  1743. else
  1744. sed 's/^X//' << \SHAR_EOF > 'io.c'
  1745. X/* Last update: 01/13/88  11:26 AM  (Edition: 5) */
  1746. X#include    <stdio.h>
  1747. X#include    <ctype.h>
  1748. X#include    <sys/file.h>
  1749. X
  1750. X#ifndef        _SGTTYB_
  1751. X#include    <sgtty.h>
  1752. X#endif
  1753. X
  1754. Xint        Term_input;
  1755. Xint        Term_output;
  1756. Xextern    int    Debug;
  1757. X/*-------------------------------------------------------------05/07/86-+
  1758. X|                                    |
  1759. X|        put_string : write out a string to Term_output        |
  1760. X|                                    |
  1761. X+----------------------------------------------------------------------*/
  1762. Xput_string (s, len)
  1763. Xchar        *s;
  1764. Xunsigned    len;
  1765. X    {
  1766. X    if (len == 0) len = strlen (s);
  1767. X    if (Debug) {
  1768. X        register int    i;
  1769. X        register char    *p = s;
  1770. X
  1771. X        for (i=0; i<len; i++) put_char (*p++);
  1772. X        }
  1773. X    else write (Term_output, s, (int)len);
  1774. X    }
  1775. X
  1776. X/*-------------------------------------------------------------05/07/86-+
  1777. X|                                    |
  1778. X|        put_char : write out one char to Term_output        |
  1779. X|                                    |
  1780. X+----------------------------------------------------------------------*/
  1781. Xput_char (c)
  1782. Xchar    c;
  1783. X    {
  1784. X    if (Debug) {
  1785. X        if (isprint(c)) write (Term_output, &c, 1);
  1786. X        else    {
  1787. X            char    buf [2];
  1788. X            buf[0] = (c < ' ') ? '^' : '~';
  1789. X            buf[1] = (c | 0x40) & 0x5f;
  1790. X            write (Term_output, buf, 2);
  1791. X            }
  1792. X        }
  1793. X    else write (Term_output, &c, 1);
  1794. X    }
  1795. X
  1796. Xstatic    char    Pushbuf [80];
  1797. Xstatic    int    Pushi = 0;
  1798. X/*-------------------------------------------------------------05/07/86-+
  1799. X|                                    |
  1800. X|        get_char : get a char from Term_input            |
  1801. X|                                    |
  1802. X+----------------------------------------------------------------------*/
  1803. Xchar
  1804. Xget_char ()
  1805. X    {
  1806. X    char        c;
  1807. X    register int    i;
  1808. X
  1809. X    if (Pushi > 0) {        /* push buffer not empty */
  1810. X        c = Pushbuf[0];
  1811. X        Pushi--;
  1812. X        for (i=0; i<Pushi; i++) {
  1813. X            Pushbuf[i] = Pushbuf[i+1];
  1814. X            }
  1815. X        return (c);
  1816. X        }
  1817. X    read (Term_input, &c, 1);
  1818. X    c &= 0x7f;            /* make it ASCII */
  1819. X    return (c);
  1820. X    }
  1821. X
  1822. Xpushback (buf, len)
  1823. Xchar    *buf;
  1824. Xint    len;
  1825. X    {
  1826. X    register char    *p = &Pushbuf [Pushi];
  1827. X
  1828. X    Pushi += len;
  1829. X    while (len-- > 0) {
  1830. X        *p++ = *buf++;
  1831. X        }
  1832. X    }
  1833. X
  1834. Xstatic    int        Old_flags;
  1835. Xstatic    struct    sgttyb    Mode_tty;
  1836. X/*-------------------------------------------------------------05/07/86-+
  1837. X|                                    |
  1838. X|         cbreakio : enter/exit cbreak I/O mode            |
  1839. X|                                    |
  1840. X+----------------------------------------------------------------------*/
  1841. Xcbreakio (n)
  1842. Xint    n;                /* 1 -- enter, 0 -- exit */
  1843. X    {
  1844. X    static    int    cbreak_io = 0;
  1845. X    int        ostate;
  1846. X
  1847. X    ostate = cbreak_io;
  1848. X    if (n) {
  1849. X        if (!cbreak_io) {
  1850. X            open_tty ();
  1851. X            cbreak_io = 1;
  1852. X            }
  1853. X        }
  1854. X    else    {
  1855. X        if (cbreak_io) {
  1856. X            close_tty ();
  1857. X            cbreak_io = 0;
  1858. X            }
  1859. X        }
  1860. X    return (ostate);
  1861. X    }
  1862. X
  1863. X/*-------------------------------------------------------------01/12/88-+
  1864. X|                                    |
  1865. X|        term_init : open terminal for read/write        |
  1866. X|                                    |
  1867. X+----------------------------------------------------------------------*/
  1868. Xterm_init ()
  1869. X    {
  1870. X    extern    char    *Prgname;
  1871. X
  1872. X    if ((Term_input = open ("/dev/tty", O_RDONLY)) < 0) {
  1873. X        perror ("term_init: open(/dev/tty,r)");
  1874. X        exit (1);
  1875. X        }
  1876. X    if ((Term_output = open ("/dev/tty", O_WRONLY)) < 0) {
  1877. X        perror ("term_init: open(/dev/tty,r)");
  1878. X        exit (1);
  1879. X        }
  1880. X
  1881. X    if (!isatty(Term_input) || !isatty(Term_output)) {
  1882. X        fprintf (stderr, "You have to run %s interactively\n",
  1883. X             Prgname);
  1884. X        exit (1);
  1885. X        }
  1886. X    }
  1887. X
  1888. X/*-------------------------------------------------------------01/12/88-+
  1889. X|                                    |
  1890. X|         term_close : close terminal descriptors        |
  1891. X|                                    |
  1892. X+----------------------------------------------------------------------*/
  1893. Xterm_close ()
  1894. X    {
  1895. X    close (Term_input);
  1896. X    close (Term_output);
  1897. X    }
  1898. X/*------------------------------------------------------------07/10/84--+
  1899. X|                                    |
  1900. X|     open_tty : open terminal in CBREAK mode without ECHO        |
  1901. X|                                    |
  1902. X+----------------------------------------------------------------------*/
  1903. Xstatic    open_tty ()
  1904. X    {
  1905. X    gtty (Term_input, &Mode_tty);
  1906. X    Old_flags = Mode_tty.sg_flags;        /* save old setting */
  1907. X    Mode_tty.sg_flags |= CBREAK;
  1908. X    Mode_tty.sg_flags &= ~(ECHO | CRMOD);
  1909. X    stty (Term_input, &Mode_tty);
  1910. X    }
  1911. X
  1912. X/*------------------------------------------------------------07/10/84--+
  1913. X|                                    |
  1914. X|    close_tty : close terminal and restore original setting        |
  1915. X|                                    |
  1916. X+----------------------------------------------------------------------*/
  1917. Xstatic    close_tty ()
  1918. X    {
  1919. X    Mode_tty.sg_flags = Old_flags;
  1920. X    stty (Term_input, &Mode_tty);        /* restore original setting */
  1921. X    }
  1922. SHAR_EOF
  1923. if test 4106 -ne "`wc -c < 'io.c'`"
  1924. then
  1925.     echo shar: error transmitting "'io.c'" '(should have been 4106 characters)'
  1926. fi
  1927. fi # end of overwriting check
  1928. echo shar: extracting "'summary.c'" '(1880 characters)'
  1929. if test -f 'summary.c'
  1930. then
  1931.     echo shar: will not over-write existing file "'summary.c'"
  1932. else
  1933. sed 's/^X//' << \SHAR_EOF > 'summary.c'
  1934. X/* Last update: 01/14/88  00:30 AM  (Edition: 14) */
  1935. X#include    <stdio.h>
  1936. X#include    "basic.h"
  1937. X#include    "form.h"
  1938. X
  1939. Xstatic char    *Summary[] = {
  1940. X"    RETURN - terminate        CTRL P or up arrow - vertical up one field",
  1941. X"    TAB    - next field       CTRL N or down arrow - vertical down one field",
  1942. X"    CTRL T - prev field       Intr char - abort",
  1943. X"    CTRL L - refresh screen   Stop char - stop process",
  1944. X"",
  1945. X"--- Editable Field ---                  --- Selection Field ---",
  1946. X"  Movement:",
  1947. X"    CTRL A - beginning of field         SPACE  - show next selection",
  1948. X"    CTRL E - end of field               CTRL H - show prev selection",
  1949. X"    CTRL F - forward one char           x      - find next selection starts",
  1950. X"             or --> key                          with character 'x'",
  1951. X"    CTRL B - backword one char          ?      - get help message (-m flag)",
  1952. X"             or <-- key or CTRL H",
  1953. X"  Editing:",
  1954. X"    CTRL U - delete to start of field",
  1955. X"    CTRL K - delete to end of field",
  1956. X"    CTRL W - delete prev word",
  1957. XNULL
  1958. X};
  1959. X
  1960. Xstatic char    *Newline = "\r\n\r\n";
  1961. Xstatic char    *Header = "Shell Form Version: ";
  1962. Xextern    char    *Version;
  1963. Xextern    char    *Copyright;
  1964. Xextern    char    *Bugs;
  1965. Xextern    char    get_char();
  1966. X/*-------------------------------------------------------------01/13/88-+
  1967. X|                                    |
  1968. X|         show_summary : display on-line summary         |
  1969. X|                                    |
  1970. X+----------------------------------------------------------------------*/
  1971. Xshow_summary ()
  1972. X    {
  1973. X    char    **pp = Summary;
  1974. X    char    *p;
  1975. X
  1976. X    ENTER (show_summary);
  1977. X    screen (SCR_ERASE);
  1978. X    put_string (Header, 0);    put_string (Version, 0);
  1979. X    put_string (Newline, 2);
  1980. X    put_string (Copyright, 0); put_string (Newline, 2);
  1981. X    put_string (Bugs, 0);      put_string (Newline, 4);
  1982. X    while ((p = *pp++) != NULL) {
  1983. X        put_string (p, 0);
  1984. X        put_string (Newline, 2);
  1985. X        }
  1986. X    put_string ("\r\n     Press SPACE to continue: ", 0);
  1987. X    while (get_char() != ' ');
  1988. X    EXIT;
  1989. X    }
  1990. SHAR_EOF
  1991. if test 1880 -ne "`wc -c < 'summary.c'`"
  1992. then
  1993.     echo shar: error transmitting "'summary.c'" '(should have been 1880 characters)'
  1994. fi
  1995. fi # end of overwriting check
  1996. #    End of shell archive
  1997. exit 0
  1998.  
  1999.